#include "handy/handy/handy.h"
#include <algorithm>
#include <stdio.h>
#include <string>
#include <stdint.h>
#include "common.h"
#include "xudp.pb.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
using namespace std;
using namespace handy;

int g_id = 0;
string g_content;

int main() {
	g_content = random_string(500);
	
	setloglevel("INFO");
  	setlogfile("test_client_tcp");
	EventBase base;
	Signal::signal(SIGINT, [&] { base.exit(); });
	TcpConnPtr con = TcpConn::createConnection(&base, SERVER_IP, SERVER_PORT, 3000);
	int fd = con->getChannel()->fd();
	int flag = 1;
	int result = setsockopt(fd,            /* socket affected */
		IPPROTO_TCP,     /* set option at TCP level */
		TCP_NODELAY,     /* name of option */
		(char *)&flag,  /* the cast is historical cruft */
		sizeof(int));    /* length of option value */
	if (result < 0) {
		fatal("set no delay failed");
	}
	con->setReconnectInterval(3000);
	con->onMsg(new LengthCodec, [](const TcpConnPtr& con, Slice msg) {
		info("recv msg: %.*s", (int)msg.size(), msg.data());
	});

	con->onState([=](const TcpConnPtr& con) {
		info("onState called state: %d", con->getState());
		if (con->getState() == TcpConn::Connected) {
			info("connect ok");
		}
	});

	char buf[1000] = {};
	base.runAfter(0, [&]() {
		if (con->getState() == TcpConn::Connected) {
			xmsg m;
			m.set_id(g_id++);
			m.set_buf(g_content.c_str(), MSG_SIZE);
			bool succ= m.SerializeToArray(buf, sizeof(buf));
			if (!succ) {
				fatal("serize failed");
			}
			Slice s(buf, m.ByteSize());
			
			info("id:%d,time:%ld", m.id(), util::timeMilli());
			con->sendMsg(s);
		}
		if (g_id  >= MAX_MSG_ID){
			base.exit();
		}
	}, MSG_INTERVAL);
	base.loop();
	info("program exited");
}
